#pragma once
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>

#include "Room.h"

using namespace std;

class Building
{
protected:
	vector<Room> v;
	string info;
public:

	Building() : info("N/A"){ }

	Building(string info)
	{
		this->info = info;
	}

	~Building(){ }

	void Add(Room r)
	{
		v.push_back(r);
	}

	string Search(double area, type_of_room type)
	{
		ostringstream oss;
		for (auto &r : v)
		{
			if (r.getArea() == area && r.getType() == type)
			{
				oss << r << endl;
			}
		}
		return oss.str();
	}

	void Delete(int i)
	{
		v.erase(v.begin() + i);
	}

	string List()
	{
		ostringstream oss;
		for (auto &r : v)
		{
			oss << r << endl;
		}
		return oss.str();
	}

	void WriteToFile(string filename)
	{
		ofstream fout;
		try
		{
			fout.open(filename);
			fout << "Building=" << info << endl;
			for (auto &r : v)
			{
				fout << "Room=" << r << endl;
			}
		}
		catch (exception e)
		{
			cout << "Exception thrown for file: " << filename << endl;
			cout << e.what();
		}
		fout.close();
	}

	void ReadFromFile(string filename)
	{
		v.clear();
		string str, row;
		ifstream fin;
		try
		{
			fin.open(filename);
			while (getline(fin, row))
			{
				istringstream iss(row);
				getline(iss, str, '=');
				if (str.compare("Building") == 0)
				{
					iss >> info;
				}
				if (str.compare("Room") == 0)
				{
					Room r;
					iss >> r;
					if (r.getArea() != -1)
					{
						v.push_back(r);
					}
				}
			}
		}
		catch (exception e)
		{
			cout << "Exception thrown for file: " << filename << endl;
			cout << e.what();
		}
		fin.close();
	}

	double Area()
	{
		double total = 0;
		for (auto &r : v)
		{
			total += r.getArea();
		}
		return total;
	}

	void setInfo(string info){ this->info = info; }
	string getInfo(){ return info; }

	friend ostream& operator<<(ostream &out, const Building &b)
	{
		out << "Building=(" << b.info << ")" << endl;
		for (auto &r : b.v)
		{
			out << "Room=" << r << endl;
		}
		return out;
	}

	friend istream& operator>>(istream &in, Building &b)
	{
		string str;
		getline(in, str, '(');
		getline(in, b.info, ')');
		return in;
	}

	void Read()
	{
		cout << "Info: ";
		getline(cin, info);
		cout << "Please enter all the rooms in the building." << endl;
		cout << "To exit, enter blank values..." << endl;
		while (true)
		{
			Room r;
			r.Read();
			if (r.getArea() == -1)
			{
				break;
			}
			else
			{
				v.push_back(r);
			}
		}
	}

	virtual void Print()
	{
		cout << "Info: " << info;
	}
};

